Introduction

The federalist papers were written by three men: Alexander Hamilton, James Madison, and John Jay. These men wrote 85 essays to encourage the public to support the new U.S. constitution when it was not certain what would become of our new union. The essays discuss a variety of topics ranging from taxation to the role of the president. These essays helped the public understand the purpose of the constitution, what the fight was for, and what our new nation’s government would look like.

A perfect historically accurate depiction of the events can be seen here.

In this analysis of the Federalist essays, obtained from {gutenbergr}, I will explore the differences between the 3 authors. Exploration will be done through use of data summaries and data visualizations. Additionally, I will be tying in concepts from my thesis topic.

Data injection and intial formatiing can be viewed in the scripts file, or in Appendix A.

Data Reformat

Before we can do anything interesting with this data, it requires additional processing. This data is currently in the format of:

Paper No. Text Author
1 Hamilton
2 Jay

Where the “…” is the entire text for the essay. All of the analysis I would like to complete utilizes tokens. Tokens could also be called a “unit of text”; tokens may be paragraphs, sentences, bigrams, words, or even characters. I will be focusing on bigrams and words. Specifically I will be examining skip bigrams, where a bigram is produced if words fall within a specified window of each other. Lucky for me, the {tidytext} package has tokenizers for both words and skip bigrams. But before we get too deep into the analysis, we should summarize the data.

Data Summary

As stated earlier, there are 85 total essays written by these three men (if you watch the Hamilton clip you will know how many each man wrote). We may want to check out how many words are in each essay. We can do this with {tidytext}, {ggplot2}, and {dplyr}. In the below plot, Figure 1, we see that essay lengths ranged from 988 words to 5870 words! I highlighted what must have been of more importance in their minds at the time, versus what may be more concerning to us today; much more was written on Trial by Jury than was on Electing a President.

p <- federalist %>% 
  unnest_tokens(input = text, output = "word", token = "words") %>% 
  #anti_join(stop_words) %>% 
  group_by(paper_num) %>% 
  count() %>% 
  ggplot(aes(paper_num,n)) +
  #geom_bgimage(parchment) +
  geom_col(fill = "black", alpha = 0.75) +
  geom_curve(data = data.frame(x = 82.1789757789767, y = 5952.69503878185, 
                               xend = 63.5089761463646, yend = 5483.11777828242),
             mapping = aes(x = x, y = y, xend = xend, yend = yend),
             curvature = 0.305, arrow = arrow(30L, unit(0.1, "inches"),"last", "closed"),
             alpha = 1, inherit.aes = FALSE) +
  geom_curve(data = data.frame(x = 68.6950871554235, y = 3092.81934190705, 
                               xend = 59.0637381385998, yend = 3915.33373479995), 
             mapping = aes(x = x, y = y, xend = xend, yend = yend), 
             arrow = arrow(30L, unit(0.1, "inches"), "last", "closed"), 
             alpha = 1, inherit.aes = FALSE) +
  geom_text(data = data.frame(x = 47.9506431191878, y = 3872.04350359506, label = "Topic: Electing a President"),
            mapping = aes(x = x, y = y, label = label),
            size = 3.86605783866058, hjust = 0.6, alpha = 1, inherit.aes = FALSE) +
  geom_text(data = data.frame(x = 58.6192143378233, y = 5495.42717377841, label = "Topic: Trial by Jury"),
            mapping = aes(x = x, y = y, label = label),
            size = 3.86605783866058, hjust = 0.75, alpha = 1, inherit.aes = FALSE) +
  ggthemes::theme_clean() +
  theme(plot.background = element_rect(fill = "#E0C594")) +
  labs(title = "Federalist Papers", subtitle = "Figure 1",
       x = "Essay No.", y = "Number of Words")

p


#ggannotate::ggannotate(p)
federalist %>% 
  unnest_tokens(input = text, output = "word", token = "words") %>% 
  group_by(author, paper_num) %>% 
  count() %>% 
  ungroup() %>% 
  group_by(author) %>% 
  summarize(mean = mean(n),
            median = median(n),
            max = max(n),
            min = min(n))

Although the men worked together and shared ideas, Hamilton wrote the most. Let’s examine. In Figures 2 & 3, we see that Hamilton certainly wrote the most, but Madison often wrote more lengthy essays. Maybe Jay just was tired of writing? Just kidding, read more about why he didn’t write so much here (spoilers: he got very sick).

# Boxplot
p_a <- federalist %>% 
  unnest_tokens(input = text, output = "word", token = "words") %>% 
  group_by(author, paper_num) %>% 
  count() %>% 
  ungroup() %>% 
  group_by(author) %>% 
  ggplot(aes(x = author, y = n))+
  geom_boxplot(fill = NA) +
  geom_jitter(shape = 4, alpha = 0.5)+
  ggthemes::theme_clean() +
  theme(plot.background = element_rect(fill = "#E0C594")) +
  labs(title = "Essays by Author", subtitle = "Figure 2",
       x = "Author", y = "Number of Words")



# Stacked Bar
p_b <- federalist %>% 
  unnest_tokens(input = text, output = "word", token = "words") %>% 
  group_by(author, paper_num) %>% 
  count() %>% 
  ungroup() %>% 
  group_by(author) %>% 
  ggplot(aes(x = author, y = n, grouping = paper_num))+
  geom_col(color = "black", alpha = 0.5) +
  ggthemes::theme_clean() +
  theme(plot.background = element_rect(fill = "#E0C594")) +
  labs(title = "Amount Written by Author", subtitle = "Figure 3",
       x = "Author", y = "Number of Words")


p_a + p_b

So Jay didn’t write a lot (sorry Jay), Madison was working hard, and Hamilton was writing Non-Stop, but what were they writing about? Doesn’t subject matter and quality over quantity? We can explore content in the next section.

Data Analysis

TF-IDF

First, we can use the ever reliable Term Frequency-Inverse Document Frequency. This calculation can be intuitively described as how important a word is to a corpus. For our purposes, this may be how important a word is the the writings of Madison or Hamilton. Unlike when we were just assessing the sheer number of words the authors wrote, now we are concerned with content. So, at this phase we will remove stop words

library(RColorBrewer)


set.seed(23)

federalist_tf_idf <- federalist %>% 
  unnest_tokens(input = text, output = "word", token = "words") %>% 
  anti_join(stop_words) %>% 
  group_by(author, word) %>% 
  count() %>% 
  bind_tf_idf(word,author,n) 
Joining, by = "word"
p1 <- federalist_tf_idf %>% 
  group_by(author) %>% 
  slice_max(order_by = tf_idf, n = 10) %>% 
  filter(author == "HAMILTON") %>% 
  mutate(word = fct_reorder(word, tf_idf)) %>%
  ggplot(aes(word, tf_idf))+
  geom_bgimage(parchment)+
  annotation_custom(rasterGrob(ham_sig))+
  geom_col(fill = "black", color = "black", alpha = 0.5, size = 0.25)+
  coord_flip()+
  ggthemes::theme_clean() +
  theme(plot.background = element_rect(fill = "#E0C594"))
p2 <- federalist_tf_idf %>% 
  group_by(author) %>% 
  slice_max(order_by = tf_idf, n = 10) %>% 
  filter(author == "MADISON") %>% 
  mutate(word = fct_reorder(word, tf_idf)) %>%
  ggplot(aes(word, tf_idf))+
  geom_bgimage(parchment)+
  annotation_custom(rasterGrob(mad_sig))+
  geom_col(fill = "black", color = "black", alpha = 0.5, size = 0.25)+
  coord_flip()+
  ggthemes::theme_clean() +
  theme(plot.background = element_rect(fill = "#E0C594"))
p3 <- federalist_tf_idf %>% 
  group_by(author) %>% 
  slice_max(order_by = tf_idf, n = 10) %>% 
  filter(author == "JAY") %>% 
  mutate(word = fct_reorder(word, tf_idf)) %>%
  ggplot(aes(word, tf_idf))+
  geom_bgimage(parchment)+
  annotation_custom(rasterGrob(jj_sig))+
  geom_col(fill = "black", color = "black", alpha = 0.5, size = 0.25)+
  coord_flip()+
  ggthemes::theme_clean() +
  theme(plot.background = element_rect(fill = "#E0C594"))
p1 / p2 / p3

Through looking at the tf_idf values for each author, we see that:

  • Hamilton: Jury, Spirit, Extent, Objection

  • Madison: Representatives, Legislative, Republican, Branch

  • Jay: America, Obeyed, Tides, Steadily

One of the words that really popped out to me here was “tides” from Jay, who must have used a lot of ocean analogies in his writing, perhaps? Additionally, that really long paper in Figure 1 which dicussed Trial by Jury, Hamilton wrote that, so it only makes sense that this is his defining word. Madison wrote a lot on congress (House of Representatives and the Senate). He described this new mixed government and that required a lot of writing on how exactly the congress would work. This is visible in the words “Representatives”, “Legislative”, and “Republican” (republican in this context meaning a republic, where the governed are represented by elected officials).

I did mention we would want to look at bigrams in addition to words. Let’s check them out.

Skip Bigrams

As stated, for my thesis I will be writing on a tecnique that uses skip bigram graphs to measure document similarity. Again, the folks that wrote {tidytext} have packaged a difficult task into a few lines of code. With {tidytext} we con construct skip bigrams. There is a fair amount of work that needs to be done before we can just view these graphs: reformating data, cleaning data, etc. In this paper, we will only consider skip bigrams with a window width of 5 (\(k=5\)).

Let’s look at an initial graph visualization.

federalist_skip_bigram <- tidytext::unnest_tokens(federalist, output = "words" ,input = text, token = "skip_ngrams", n = 2, k = 5)
federalist_skip_bigram <- federalist_skip_bigram %>% 
  separate(words, c("word1", "word2"), sep = " ") %>% 
  anti_join(stop_words, by = c("word1" = "word")) %>% 
  anti_join(stop_words, by = c("word2" = "word")) %>% 
  filter(!is.na(word1),
         !is.na(word2))

Very messy, and we can’t read it, but that is okay for now. Later this kind of graph will be compared with other similar graphs, so we dont have to be able to read it. However, the method I am planning to use, graph kernels, often require that a graph is connected. So I just want the largest connected portion! This takes some extra work, but we can make it happen.

This is exeactly the kind of graph I need to be able to produce for my thesis. This fun example was a good way to practice cutting the extra off of the graph, in preparation for the graph kernel methods. The next step would be to make these style graphs for Madison and Jay. Alternatively, they could be made for each essay. Then graph kernels will be applied and a measure of similarity between the graphs will be produced.

Conclusions

Using text analysis, the Federalist papers can be a lot of fun to work on. There are a lot of fun tasks here: seperate text by author, seperate text by essay, who wrote Non-Stop, and who got sick after writing 5? In this project I specifically wanted to practice some {ggplot2} skills. Among those skills were: {ggannotate}, background images, and theme elements. Additionally, I wanted to do some text analysis to practice and learn how to prepare my graphs for the analysis I want to complete for me thesis work.

LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpemF0aW9uIC0gTWluaS1Qcm9qZWN0IDEiCmF1dGhvcjogIkxldmkgQy4gTmlja2xhcyBgbG5pY2tsYXM4MTgxQGZsb3JpZGFwb2x5LmVkdWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZ9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KGlncmFwaCkKbGlicmFyeShnZ3JhcGgpCmxpYnJhcnkoZ2dpbWFnZSkKbGlicmFyeShncmlkKQpsaWJyYXJ5KHBuZykKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZ2dhbm5vdGF0ZSkKCiMgRGF0YQpmZWRlcmFsaXN0IDwtIHJlYWRfcmRzKCIuLi9kYXRhL3RpZHlfZmVkZXJhbGlzdC5SRFMiKQoKIyBFeHRyYXMKcGFyY2htZW50IDwtICIuLi9pbWFnZXMvcGFyY2htZW50LnBuZyIKaGFtX3NpZyA8LSBwbmc6OnJlYWRQTkcoIi4uL2ltYWdlcy9BSGFtLnBuZyIpCm1hZF9zaWcgPC0gcG5nOjpyZWFkUE5HKCIuLi9pbWFnZXMvSmFtZXNNYWRpc29uLnBuZyIpCmpqX3NpZyA8LSBwbmc6OnJlYWRQTkcoIi4uL2ltYWdlcy9qal9zaWcucG5nIikKYGBgCgoKCiMgSW50cm9kdWN0aW9uCgpUaGUgZmVkZXJhbGlzdCBwYXBlcnMgd2VyZSB3cml0dGVuIGJ5IHRocmVlIG1lbjogQWxleGFuZGVyIEhhbWlsdG9uLCBKYW1lcyBNYWRpc29uLCBhbmQgSm9obiBKYXkuIFRoZXNlIG1lbiB3cm90ZSA4NSBlc3NheXMgdG8gZW5jb3VyYWdlIHRoZSBwdWJsaWMgdG8gc3VwcG9ydCB0aGUgbmV3IFUuUy4gY29uc3RpdHV0aW9uIHdoZW4gaXQgd2FzIG5vdCBjZXJ0YWluIHdoYXQgd291bGQgYmVjb21lIG9mIG91ciBuZXcgdW5pb24uIFRoZSBlc3NheXMgZGlzY3VzcyBhIHZhcmlldHkgb2YgdG9waWNzIHJhbmdpbmcgZnJvbSB0YXhhdGlvbiB0byB0aGUgcm9sZSBvZiB0aGUgcHJlc2lkZW50LiBUaGVzZSBlc3NheXMgaGVscGVkIHRoZSBwdWJsaWMgdW5kZXJzdGFuZCB0aGUgcHVycG9zZSBvZiB0aGUgY29uc3RpdHV0aW9uLCB3aGF0IHRoZSBmaWdodCB3YXMgZm9yLCBhbmQgd2hhdCBvdXIgbmV3IG5hdGlvbidzIGdvdmVybm1lbnQgd291bGQgbG9vayBsaWtlLiAKCkEgfn5wZXJmZWN0IGhpc3RvcmljYWxseSBhY2N1cmF0ZX5+IGRlcGljdGlvbiBvZiB0aGUgZXZlbnRzIGNhbiBiZSBzZWVuIFtoZXJlXShodHRwczovL3lvdXR1LmJlL0RwQ2VKa1RCMV9RP3Q9MjU0KS4KIVtdKGh0dHA6Ly9yZXNpZGVudC5jb20vbmV3L3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE2LzA0L2hhbWlsdG9uLmpwZykKCkluIHRoaXMgYW5hbHlzaXMgb2YgdGhlIEZlZGVyYWxpc3QgZXNzYXlzLCBvYnRhaW5lZCBmcm9tIGB7Z3V0ZW5iZXJncn1gLCBJIHdpbGwgZXhwbG9yZSB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgMyBhdXRob3JzLiBFeHBsb3JhdGlvbiB3aWxsIGJlIGRvbmUgdGhyb3VnaCB1c2Ugb2YgZGF0YSBzdW1tYXJpZXMgYW5kIGRhdGEgdmlzdWFsaXphdGlvbnMuIEFkZGl0aW9uYWxseSwgSSB3aWxsIGJlIHR5aW5nIGluIGNvbmNlcHRzIGZyb20gbXkgdGhlc2lzIHRvcGljLiAKCl9EYXRhIGluamVjdGlvbiBhbmQgaW50aWFsIGZvcm1hdGlpbmcgY2FuIGJlIHZpZXdlZCBpbiB0aGUgYHNjcmlwdHNgIGZpbGUsIG9yIGluIEFwcGVuZGl4IEEuXwoKCiMgRGF0YSBSZWZvcm1hdApCZWZvcmUgd2UgY2FuIGRvIGFueXRoaW5nIGludGVyZXN0aW5nIHdpdGggdGhpcyBkYXRhLCBpdCByZXF1aXJlcyBhZGRpdGlvbmFsIHByb2Nlc3NpbmcuIFRoaXMgZGF0YSBpcyBjdXJyZW50bHkgaW4gdGhlIGZvcm1hdCBvZjoKClBhcGVyIE5vLiB8IFRleHQgfCBBdXRob3IKLS0tLS0tLS0tLXwtLS0tLS18LS0tLS0tLQoxIHwgLi4uIHwgSGFtaWx0b24KMiB8IC4uLiB8IEpheQoKV2hlcmUgdGhlICIuLi4iIGlzIHRoZSBlbnRpcmUgdGV4dCBmb3IgdGhlIGVzc2F5LiBBbGwgb2YgdGhlIGFuYWx5c2lzIEkgd291bGQgbGlrZSB0byBjb21wbGV0ZSB1dGlsaXplcyAqKnRva2VucyoqLiBUb2tlbnMgY291bGQgYWxzbyBiZSBjYWxsZWQgYSAidW5pdCBvZiB0ZXh0IjsgdG9rZW5zIG1heSBiZSBwYXJhZ3JhcGhzLCBzZW50ZW5jZXMsICpiaWdyYW1zKiwgKip3b3JkcyoqLCBvciBldmVuIGNoYXJhY3RlcnMuIEkgd2lsbCBiZSBmb2N1c2luZyBvbiBfYmlncmFtc18gYW5kIF93b3Jkc18uIFNwZWNpZmljYWxseSBJIHdpbGwgYmUgZXhhbWluaW5nICoqc2tpcCBiaWdyYW1zKiosIHdoZXJlIGEgYmlncmFtIGlzIHByb2R1Y2VkIGlmIHdvcmRzIGZhbGwgd2l0aGluIGEgc3BlY2lmaWVkIHdpbmRvdyBvZiBlYWNoIG90aGVyLiBMdWNreSBmb3IgbWUsIHRoZSBge3RpZHl0ZXh0fWAgcGFja2FnZSBoYXMgdG9rZW5pemVycyBmb3IgYm90aCB3b3JkcyBhbmQgc2tpcCBiaWdyYW1zLiBCdXQgYmVmb3JlIHdlIGdldCB0b28gZGVlcCBpbnRvIHRoZSBhbmFseXNpcywgd2Ugc2hvdWxkIHN1bW1hcml6ZSB0aGUgZGF0YS4KCiMgRGF0YSBTdW1tYXJ5CgpBcyBzdGF0ZWQgZWFybGllciwgdGhlcmUgYXJlIDg1IHRvdGFsIGVzc2F5cyB3cml0dGVuIGJ5IHRoZXNlIHRocmVlIG1lbiAoaWYgeW91IHdhdGNoIHRoZSBfSGFtaWx0b25fIGNsaXAgeW91IHdpbGwga25vdyBob3cgbWFueSBlYWNoIG1hbiB3cm90ZSkuIFdlIG1heSB3YW50IHRvIGNoZWNrIG91dCBob3cgbWFueSB3b3JkcyBhcmUgaW4gZWFjaCBlc3NheS4gV2UgY2FuIGRvIHRoaXMgd2l0aCBge3RpZHl0ZXh0fWAsIGB7Z2dwbG90Mn1gLCBhbmQgYHtkcGx5cn1gLiBJbiB0aGUgYmVsb3cgcGxvdCwgRmlndXJlIDEsIHdlIHNlZSB0aGF0IGVzc2F5IGxlbmd0aHMgcmFuZ2VkIGZyb20gOTg4IHdvcmRzIHRvIDU4NzAgd29yZHMhIEkgaGlnaGxpZ2h0ZWQgd2hhdCBtdXN0IGhhdmUgYmVlbiBvZiBtb3JlIGltcG9ydGFuY2UgaW4gdGhlaXIgbWluZHMgYXQgdGhlIHRpbWUsIHZlcnN1cyB3aGF0IG1heSBiZSBtb3JlIGNvbmNlcm5pbmcgdG8gdXMgdG9kYXk7IG11Y2ggbW9yZSB3YXMgd3JpdHRlbiBvbiBfVHJpYWwgYnkgSnVyeV8gdGhhbiB3YXMgb24gX0VsZWN0aW5nIGEgUHJlc2lkZW50Xy4gCgpgYGB7ciB3b3Jkcy1wZXItZG9jLCBtZXNzYWdlID0gRn0KcCA8LSBmZWRlcmFsaXN0ICU+JSAKICB1bm5lc3RfdG9rZW5zKGlucHV0ID0gdGV4dCwgb3V0cHV0ID0gIndvcmQiLCB0b2tlbiA9ICJ3b3JkcyIpICU+JSAKICAjYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JSAKICBncm91cF9ieShwYXBlcl9udW0pICU+JSAKICBjb3VudCgpICU+JSAKICBnZ3Bsb3QoYWVzKHBhcGVyX251bSxuKSkgKwogICNnZW9tX2JnaW1hZ2UocGFyY2htZW50KSArCiAgZ2VvbV9jb2woZmlsbCA9ICJibGFjayIsIGFscGhhID0gMC43NSkgKwogIGdlb21fY3VydmUoZGF0YSA9IGRhdGEuZnJhbWUoeCA9IDgyLjE3ODk3NTc3ODk3NjcsIHkgPSA1OTUyLjY5NTAzODc4MTg1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhlbmQgPSA2My41MDg5NzYxNDYzNjQ2LCB5ZW5kID0gNTQ4My4xMTc3NzgyODI0MiksCiAgICAgICAgICAgICBtYXBwaW5nID0gYWVzKHggPSB4LCB5ID0geSwgeGVuZCA9IHhlbmQsIHllbmQgPSB5ZW5kKSwKICAgICAgICAgICAgIGN1cnZhdHVyZSA9IDAuMzA1LCBhcnJvdyA9IGFycm93KDMwTCwgdW5pdCgwLjEsICJpbmNoZXMiKSwibGFzdCIsICJjbG9zZWQiKSwKICAgICAgICAgICAgIGFscGhhID0gMSwgaW5oZXJpdC5hZXMgPSBGQUxTRSkgKwogIGdlb21fY3VydmUoZGF0YSA9IGRhdGEuZnJhbWUoeCA9IDY4LjY5NTA4NzE1NTQyMzUsIHkgPSAzMDkyLjgxOTM0MTkwNzA1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhlbmQgPSA1OS4wNjM3MzgxMzg1OTk4LCB5ZW5kID0gMzkxNS4zMzM3MzQ3OTk5NSksIAogICAgICAgICAgICAgbWFwcGluZyA9IGFlcyh4ID0geCwgeSA9IHksIHhlbmQgPSB4ZW5kLCB5ZW5kID0geWVuZCksIAogICAgICAgICAgICAgYXJyb3cgPSBhcnJvdygzMEwsIHVuaXQoMC4xLCAiaW5jaGVzIiksICJsYXN0IiwgImNsb3NlZCIpLCAKICAgICAgICAgICAgIGFscGhhID0gMSwgaW5oZXJpdC5hZXMgPSBGQUxTRSkgKwogIGdlb21fdGV4dChkYXRhID0gZGF0YS5mcmFtZSh4ID0gNDcuOTUwNjQzMTE5MTg3OCwgeSA9IDM4NzIuMDQzNTAzNTk1MDYsIGxhYmVsID0gIlRvcGljOiBFbGVjdGluZyBhIFByZXNpZGVudCIpLAogICAgICAgICAgICBtYXBwaW5nID0gYWVzKHggPSB4LCB5ID0geSwgbGFiZWwgPSBsYWJlbCksCiAgICAgICAgICAgIHNpemUgPSAzLjg2NjA1NzgzODY2MDU4LCBoanVzdCA9IDAuNiwgYWxwaGEgPSAxLCBpbmhlcml0LmFlcyA9IEZBTFNFKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBkYXRhLmZyYW1lKHggPSA1OC42MTkyMTQzMzc4MjMzLCB5ID0gNTQ5NS40MjcxNzM3Nzg0MSwgbGFiZWwgPSAiVG9waWM6IFRyaWFsIGJ5IEp1cnkiKSwKICAgICAgICAgICAgbWFwcGluZyA9IGFlcyh4ID0geCwgeSA9IHksIGxhYmVsID0gbGFiZWwpLAogICAgICAgICAgICBzaXplID0gMy44NjYwNTc4Mzg2NjA1OCwgaGp1c3QgPSAwLjc1LCBhbHBoYSA9IDEsIGluaGVyaXQuYWVzID0gRkFMU0UpICsKICBnZ3RoZW1lczo6dGhlbWVfY2xlYW4oKSArCiAgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0UwQzU5NCIpKSArCiAgbGFicyh0aXRsZSA9ICJGZWRlcmFsaXN0IFBhcGVycyIsIHN1YnRpdGxlID0gIkZpZ3VyZSAxIiwKICAgICAgIHggPSAiRXNzYXkgTm8uIiwgeSA9ICJOdW1iZXIgb2YgV29yZHMiKQoKcAoKI2dnYW5ub3RhdGU6OmdnYW5ub3RhdGUocCkKYGBgCgpgYGB7ciBkYXRhLXN1bW1hcnksIG1lc3NhZ2UgPSBGfQpmZWRlcmFsaXN0ICU+JSAKICB1bm5lc3RfdG9rZW5zKGlucHV0ID0gdGV4dCwgb3V0cHV0ID0gIndvcmQiLCB0b2tlbiA9ICJ3b3JkcyIpICU+JSAKICBncm91cF9ieShhdXRob3IsIHBhcGVyX251bSkgJT4lIAogIGNvdW50KCkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoYXV0aG9yKSAlPiUgCiAgc3VtbWFyaXplKG1lYW4gPSBtZWFuKG4pLAogICAgICAgICAgICBtZWRpYW4gPSBtZWRpYW4obiksCiAgICAgICAgICAgIG1heCA9IG1heChuKSwKICAgICAgICAgICAgbWluID0gbWluKG4pKQpgYGAKCkFsdGhvdWdoIHRoZSBtZW4gd29ya2VkIHRvZ2V0aGVyIGFuZCBzaGFyZWQgaWRlYXMsIEhhbWlsdG9uIHdyb3RlIHRoZSBtb3N0LiBMZXQncyBleGFtaW5lLiBJbiBGaWd1cmVzIDIgJiAzLCB3ZSBzZWUgdGhhdCBIYW1pbHRvbiBjZXJ0YWlubHkgd3JvdGUgdGhlIG1vc3QsIGJ1dCBNYWRpc29uIG9mdGVuIHdyb3RlIG1vcmUgbGVuZ3RoeSBlc3NheXMuIE1heWJlIEpheSBqdXN0IHdhcyB0aXJlZCBvZiB3cml0aW5nPyBKdXN0IGtpZGRpbmcsIHJlYWQgbW9yZSBhYm91dCB3aHkgaGUgZGlkbid0IHdyaXRlIHNvIG11Y2ggW2hlcmVdKGh0dHBzOi8vd3d3Lmhpc3RvcnkuY29tL3RvcGljcy9lYXJseS11cy9mZWRlcmFsaXN0LXBhcGVycykgKHNwb2lsZXJzOiBoZSBnb3QgdmVyeSBzaWNrKS4gCgpgYGB7ciBhdXRob3ItZXhwbG9yYXRpb259CiMgQm94cGxvdApwX2EgPC0gZmVkZXJhbGlzdCAlPiUgCiAgdW5uZXN0X3Rva2VucyhpbnB1dCA9IHRleHQsIG91dHB1dCA9ICJ3b3JkIiwgdG9rZW4gPSAid29yZHMiKSAlPiUgCiAgZ3JvdXBfYnkoYXV0aG9yLCBwYXBlcl9udW0pICU+JSAKICBjb3VudCgpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGF1dGhvcikgJT4lIAogIGdncGxvdChhZXMoeCA9IGF1dGhvciwgeSA9IG4pKSsKICBnZW9tX2JveHBsb3QoZmlsbCA9IE5BKSArCiAgZ2VvbV9qaXR0ZXIoc2hhcGUgPSA0LCBhbHBoYSA9IDAuNSkrCiAgZ2d0aGVtZXM6OnRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNFMEM1OTQiKSkgKwogIGxhYnModGl0bGUgPSAiRXNzYXlzIGJ5IEF1dGhvciIsIHN1YnRpdGxlID0gIkZpZ3VyZSAyIiwKICAgICAgIHggPSAiQXV0aG9yIiwgeSA9ICJOdW1iZXIgb2YgV29yZHMiKQoKIyBTdGFja2VkIEJhcgpwX2IgPC0gZmVkZXJhbGlzdCAlPiUgCiAgdW5uZXN0X3Rva2VucyhpbnB1dCA9IHRleHQsIG91dHB1dCA9ICJ3b3JkIiwgdG9rZW4gPSAid29yZHMiKSAlPiUgCiAgZ3JvdXBfYnkoYXV0aG9yLCBwYXBlcl9udW0pICU+JSAKICBjb3VudCgpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGF1dGhvcikgJT4lIAogIGdncGxvdChhZXMoeCA9IGF1dGhvciwgeSA9IG4sIGdyb3VwaW5nID0gcGFwZXJfbnVtKSkrCiAgZ2VvbV9jb2woY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSkgKwogIGdndGhlbWVzOjp0aGVtZV9jbGVhbigpICsKICB0aGVtZShwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRTBDNTk0IikpICsKICBsYWJzKHRpdGxlID0gIkFtb3VudCBXcml0dGVuIGJ5IEF1dGhvciIsIHN1YnRpdGxlID0gIkZpZ3VyZSAzIiwKICAgICAgIHggPSAiQXV0aG9yIiwgeSA9ICJOdW1iZXIgb2YgV29yZHMiKQoKCnBfYSArIHBfYgoKYGBgCgpTbyBKYXkgZGlkbid0IHdyaXRlIGEgbG90IChzb3JyeSBKYXkpLCBNYWRpc29uIHdhcyB3b3JraW5nIGhhcmQsIGFuZCBIYW1pbHRvbiB3YXMgd3JpdGluZyBbTm9uLVN0b3BdKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9cTlpTGZQUDRQczgpLCBidXQgd2hhdCB3ZXJlIHRoZXkgd3JpdGluZyBhYm91dD8gRG9lc24ndCBzdWJqZWN0IG1hdHRlciBhbmQgcXVhbGl0eSBvdmVyIHF1YW50aXR5PyBXZSBjYW4gZXhwbG9yZSBjb250ZW50IGluIHRoZSBuZXh0IHNlY3Rpb24uCgojIERhdGEgQW5hbHlzaXMKIyMgVEYtSURGCgpGaXJzdCwgd2UgY2FuIHVzZSB0aGUgZXZlciByZWxpYWJsZSAqKlRlcm0gRnJlcXVlbmN5LUludmVyc2UgRG9jdW1lbnQgRnJlcXVlbmN5KiouIFRoaXMgY2FsY3VsYXRpb24gY2FuIGJlIGludHVpdGl2ZWx5IGRlc2NyaWJlZCBhcyBfaG93IGltcG9ydGFudCBhIHdvcmQgaXMgdG8gYSBjb3JwdXNfLiBGb3Igb3VyIHB1cnBvc2VzLCB0aGlzIG1heSBiZSBob3cgaW1wb3J0YW50IGEgd29yZCBpcyB0aGUgdGhlIHdyaXRpbmdzIG9mIE1hZGlzb24gb3IgSGFtaWx0b24uIFVubGlrZSB3aGVuIHdlIHdlcmUganVzdCBhc3Nlc3NpbmcgdGhlIHNoZWVyIG51bWJlciBvZiB3b3JkcyB0aGUgYXV0aG9ycyB3cm90ZSwgbm93IHdlIGFyZSBjb25jZXJuZWQgd2l0aCBjb250ZW50LiBTbywgYXQgdGhpcyBwaGFzZSB3ZSB3aWxsIHJlbW92ZSAqKnN0b3Agd29yZHMqKgoKYGBge3IgdGZfaWRmMSwgbWVzc2FnZSA9IEZ9CmxpYnJhcnkoUkNvbG9yQnJld2VyKQoKCnNldC5zZWVkKDIzKQoKZmVkZXJhbGlzdF90Zl9pZGYgPC0gZmVkZXJhbGlzdCAlPiUgCiAgdW5uZXN0X3Rva2VucyhpbnB1dCA9IHRleHQsIG91dHB1dCA9ICJ3b3JkIiwgdG9rZW4gPSAid29yZHMiKSAlPiUgCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JSAKICBncm91cF9ieShhdXRob3IsIHdvcmQpICU+JSAKICBjb3VudCgpICU+JSAKICBiaW5kX3RmX2lkZih3b3JkLGF1dGhvcixuKSAKCnAxIDwtIGZlZGVyYWxpc3RfdGZfaWRmICU+JSAKICBncm91cF9ieShhdXRob3IpICU+JSAKICBzbGljZV9tYXgob3JkZXJfYnkgPSB0Zl9pZGYsIG4gPSAxMCkgJT4lIAogIGZpbHRlcihhdXRob3IgPT0gIkhBTUlMVE9OIikgJT4lIAogIG11dGF0ZSh3b3JkID0gZmN0X3Jlb3JkZXIod29yZCwgdGZfaWRmKSkgJT4lCiAgZ2dwbG90KGFlcyh3b3JkLCB0Zl9pZGYpKSsKICBnZW9tX2JnaW1hZ2UocGFyY2htZW50KSsKICBhbm5vdGF0aW9uX2N1c3RvbShyYXN0ZXJHcm9iKGhhbV9zaWcpKSsKICBnZW9tX2NvbChmaWxsID0gImJsYWNrIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSwgc2l6ZSA9IDAuMjUpKwogIGNvb3JkX2ZsaXAoKSsKICBnZ3RoZW1lczo6dGhlbWVfY2xlYW4oKSArCiAgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0UwQzU5NCIpKQpgYGAKCmBgYHtyIHRmX2lkZjIsIG1lc3NhZ2U9Rn0KcDIgPC0gZmVkZXJhbGlzdF90Zl9pZGYgJT4lIAogIGdyb3VwX2J5KGF1dGhvcikgJT4lIAogIHNsaWNlX21heChvcmRlcl9ieSA9IHRmX2lkZiwgbiA9IDEwKSAlPiUgCiAgZmlsdGVyKGF1dGhvciA9PSAiTUFESVNPTiIpICU+JSAKICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHRmX2lkZikpICU+JQogIGdncGxvdChhZXMod29yZCwgdGZfaWRmKSkrCiAgZ2VvbV9iZ2ltYWdlKHBhcmNobWVudCkrCiAgYW5ub3RhdGlvbl9jdXN0b20ocmFzdGVyR3JvYihtYWRfc2lnKSkrCiAgZ2VvbV9jb2woZmlsbCA9ICJibGFjayIsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjUsIHNpemUgPSAwLjI1KSsKICBjb29yZF9mbGlwKCkrCiAgZ2d0aGVtZXM6OnRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNFMEM1OTQiKSkKCmBgYAoKYGBge3IgdGZfaWRmMywgbWVzc2FnZSA9IEZ9CnAzIDwtIGZlZGVyYWxpc3RfdGZfaWRmICU+JSAKICBncm91cF9ieShhdXRob3IpICU+JSAKICBzbGljZV9tYXgob3JkZXJfYnkgPSB0Zl9pZGYsIG4gPSAxMCkgJT4lIAogIGZpbHRlcihhdXRob3IgPT0gIkpBWSIpICU+JSAKICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHRmX2lkZikpICU+JQogIGdncGxvdChhZXMod29yZCwgdGZfaWRmKSkrCiAgZ2VvbV9iZ2ltYWdlKHBhcmNobWVudCkrCiAgYW5ub3RhdGlvbl9jdXN0b20ocmFzdGVyR3JvYihqal9zaWcpKSsKICBnZW9tX2NvbChmaWxsID0gImJsYWNrIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSwgc2l6ZSA9IDAuMjUpKwogIGNvb3JkX2ZsaXAoKSsKICBnZ3RoZW1lczo6dGhlbWVfY2xlYW4oKSArCiAgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0UwQzU5NCIpKQpgYGAKCmBgYHtyIGNvbWJpbmVfdGZfaWRmfQpwMSAvIHAyIC8gcDMKYGBgCgpUaHJvdWdoIGxvb2tpbmcgYXQgdGhlIGB0Zl9pZGZgIHZhbHVlcyBmb3IgZWFjaCBhdXRob3IsIHdlIHNlZSB0aGF0OgoKLSBIYW1pbHRvbjogSnVyeSwgU3Bpcml0LCBFeHRlbnQsIE9iamVjdGlvbgoKLSBNYWRpc29uOiBSZXByZXNlbnRhdGl2ZXMsIExlZ2lzbGF0aXZlLCBSZXB1YmxpY2FuLCBCcmFuY2gKCi0gSmF5OiBBbWVyaWNhLCBPYmV5ZWQsIFRpZGVzLCBTdGVhZGlseQoKT25lIG9mIHRoZSB3b3JkcyB0aGF0IHJlYWxseSBwb3BwZWQgb3V0IHRvIG1lIGhlcmUgd2FzICJ0aWRlcyIgZnJvbSBKYXksIHdobyBtdXN0IGhhdmUgdXNlZCBhIGxvdCBvZiBvY2VhbiBhbmFsb2dpZXMgaW4gaGlzIHdyaXRpbmcsIHBlcmhhcHM/IEFkZGl0aW9uYWxseSwgdGhhdCByZWFsbHkgbG9uZyBwYXBlciBpbiBGaWd1cmUgMSB3aGljaCBkaWN1c3NlZCBfVHJpYWwgYnkgSnVyeV8sIEhhbWlsdG9uIHdyb3RlIHRoYXQsIHNvIGl0IG9ubHkgbWFrZXMgc2Vuc2UgdGhhdCB0aGlzIGlzIGhpcyBkZWZpbmluZyB3b3JkLiBNYWRpc29uIHdyb3RlIGEgbG90IG9uIGNvbmdyZXNzIChIb3VzZSBvZiBSZXByZXNlbnRhdGl2ZXMgYW5kIHRoZSBTZW5hdGUpLiBIZSBkZXNjcmliZWQgdGhpcyBuZXcgX21peGVkIGdvdmVybm1lbnRfIGFuZCB0aGF0IHJlcXVpcmVkIGEgbG90IG9mIHdyaXRpbmcgb24gaG93IGV4YWN0bHkgdGhlIGNvbmdyZXNzIHdvdWxkIHdvcmsuIFRoaXMgaXMgdmlzaWJsZSBpbiB0aGUgd29yZHMgIlJlcHJlc2VudGF0aXZlcyIsICJMZWdpc2xhdGl2ZSIsIGFuZCAiUmVwdWJsaWNhbiIgKHJlcHVibGljYW4gaW4gdGhpcyBjb250ZXh0IG1lYW5pbmcgYSByZXB1YmxpYywgd2hlcmUgdGhlIGdvdmVybmVkIGFyZSByZXByZXNlbnRlZCBieSBlbGVjdGVkIG9mZmljaWFscykuIAoKSSBkaWQgbWVudGlvbiB3ZSB3b3VsZCB3YW50IHRvIGxvb2sgYXQgYmlncmFtcyBpbiBhZGRpdGlvbiB0byB3b3Jkcy4gTGV0J3MgY2hlY2sgdGhlbSBvdXQuCgojIyBTa2lwIEJpZ3JhbXMKCkFzIHN0YXRlZCwgZm9yIG15IHRoZXNpcyBJIHdpbGwgYmUgd3JpdGluZyBvbiBhIHRlY25pcXVlIHRoYXQgdXNlcyBfc2tpcCBiaWdyYW1fIGdyYXBocyB0byBtZWFzdXJlIGRvY3VtZW50IHNpbWlsYXJpdHkuIEFnYWluLCB0aGUgZm9sa3MgdGhhdCB3cm90ZSBge3RpZHl0ZXh0fWAgaGF2ZSBwYWNrYWdlZCBhIGRpZmZpY3VsdCB0YXNrIGludG8gYSBmZXcgbGluZXMgb2YgY29kZS4gV2l0aCBge3RpZHl0ZXh0fWAgd2UgY29uIGNvbnN0cnVjdCBza2lwIGJpZ3JhbXMuIFRoZXJlIGlzIGEgZmFpciBhbW91bnQgb2Ygd29yayB0aGF0IG5lZWRzIHRvIGJlIGRvbmUgYmVmb3JlIHdlIGNhbiBqdXN0IHZpZXcgdGhlc2UgZ3JhcGhzOiByZWZvcm1hdGluZyBkYXRhLCBjbGVhbmluZyBkYXRhLCBldGMuIEluIHRoaXMgcGFwZXIsIHdlIHdpbGwgb25seSBjb25zaWRlciBza2lwIGJpZ3JhbXMgd2l0aCBhIHdpbmRvdyB3aWR0aCBvZiA1ICgkaz01JCkuCgpMZXQncyBsb29rIGF0IGFuIGluaXRpYWwgZ3JhcGggdmlzdWFsaXphdGlvbi4KCmBgYHtyIHJlZm9ybWF0LTF9CmZlZGVyYWxpc3Rfc2tpcF9iaWdyYW0gPC0gdGlkeXRleHQ6OnVubmVzdF90b2tlbnMoZmVkZXJhbGlzdCwgb3V0cHV0ID0gIndvcmRzIiAsaW5wdXQgPSB0ZXh0LCB0b2tlbiA9ICJza2lwX25ncmFtcyIsIG4gPSAyLCBrID0gNSkKYGBgCgpgYGB7ciByZWZvcm1hdC0yLCBlcnJvciA9IEYsIHdhcm5pbmcgPSBGLCBtZXNzYWdlID0gRn0KZmVkZXJhbGlzdF9za2lwX2JpZ3JhbSA8LSBmZWRlcmFsaXN0X3NraXBfYmlncmFtICU+JSAKICBzZXBhcmF0ZSh3b3JkcywgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUgCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gYygid29yZDEiID0gIndvcmQiKSkgJT4lIAogIGFudGlfam9pbihzdG9wX3dvcmRzLCBieSA9IGMoIndvcmQyIiA9ICJ3b3JkIikpICU+JSAKICBmaWx0ZXIoIWlzLm5hKHdvcmQxKSwKICAgICAgICAgIWlzLm5hKHdvcmQyKSkKYGBgCgpgYGB7ciB2aXN1YWwyfQpmZWRfc2tpcF9iaWdyYW1fZ3JhcGggPC0gZmVkZXJhbGlzdF9za2lwX2JpZ3JhbSAlPiUgCiAgZmlsdGVyKGF1dGhvciA9PSAiSEFNSUxUT04iKSAlPiUgCiAgZ3JvdXBfYnkod29yZDEsIHdvcmQyKSAlPiUgCiAgY291bnQoKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKSAlPiUgCiAgZmlsdGVyKG4gPiA1KSAlPiUgCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKCkKCmZlZF9za2lwX2JpZ3JhbV9ncmFwaCAlPiUgCiAgZ2dyYXBoKGxheW91dCA9ICJmciIpICsKICBnZW9tX2VkZ2VfbGluaygpICsKICBnZW9tX25vZGVfcG9pbnQoKSArCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSArCiAgZ2d0aXRsZSgiSGFtaWx0b246ICBTa2lwIEJpZ3JhbXMiKQpgYGAKClZlcnkgbWVzc3ksIGFuZCB3ZSBjYW4ndCByZWFkIGl0LCBidXQgdGhhdCBpcyBva2F5IGZvciBub3cuIExhdGVyIHRoaXMga2luZCBvZiBncmFwaCB3aWxsIGJlIGNvbXBhcmVkIHdpdGggb3RoZXIgc2ltaWxhciBncmFwaHMsIHNvIHdlIGRvbnQgaGF2ZSB0byBiZSBhYmxlIHRvIHJlYWQgaXQuIEhvd2V2ZXIsIHRoZSBtZXRob2QgSSBhbSBwbGFubmluZyB0byB1c2UsIGdyYXBoIGtlcm5lbHMsIG9mdGVuIHJlcXVpcmUgdGhhdCBhIGdyYXBoIGlzIGNvbm5lY3RlZC4gU28gSSBqdXN0IHdhbnQgdGhlIGxhcmdlc3QgY29ubmVjdGVkIHBvcnRpb24hIFRoaXMgdGFrZXMgc29tZSBleHRyYSB3b3JrLCBidXQgd2UgY2FuIG1ha2UgaXQgaGFwcGVuLgoKYGBge3IgY2xpcXVlc30KIyBIb3cgbWFueSB2ZXJ0Y2llcz8KZmVkX3NraXBfYmlncmFtX2dyYXBoICU+JSAKaWdyYXBoOjp2ZXJ0ZXguYXR0cmlidXRlcygpCgojIElEIENsdXN0ZXJzCmZlZF9oYW1fY2x1c3RlcnMgPC0gZmVkX3NraXBfYmlncmFtX2dyYXBoICU+JSAKICBpZ3JhcGg6OmNsdXN0ZXJzKCkKZmVkX2hhbV9jbHVzdGVycyA8LSBmZWRfaGFtX2NsdXN0ZXJzJG1lbWJlcnNoaXAgJT4lIAogIGFzLmRhdGEuZnJhbWUoKQogCmZlZF9oYW1fY2x1c3RlcnMkd29yZCA8LSByb3duYW1lcyhmZWRfaGFtX2NsdXN0ZXJzKQpjb2xuYW1lcyhmZWRfaGFtX2NsdXN0ZXJzKSA8LSBjKCJtZW1iZXIiLCJ3b3JkIikKCnJlZHVjZWRfY2x1c3RlcnMgPC0gZmVkX2hhbV9jbHVzdGVycyAlPiUgCiAgZmlsdGVyKG1lbWJlciAhPSAxKQoKcGFyY2htZW50IDwtIHBuZzo6cmVhZFBORygiLi4vaW1hZ2VzL3BhcmNobWVudC5wbmciKQoKZmVkX3NraXBfYmlncmFtX2dyYXBoICU+JSAKICBhc19lZGdlbGlzdCgpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGFudGlfam9pbih5ID0gcmVkdWNlZF9jbHVzdGVycywgYnkgPSBjKCJWMSIgPSAid29yZCIpKSAlPiUgCiAgYW50aV9qb2luKHkgPSByZWR1Y2VkX2NsdXN0ZXJzLCBieSA9IGMoIlYyIiA9ICJ3b3JkIikpICU+JSAKICBncmFwaF9mcm9tX2RhdGFfZnJhbWUoKSAlPiUgCiAgZ2dyYXBoKGxheW91dCA9ICJmciIpICsKICBhbm5vdGF0aW9uX2N1c3RvbShyYXN0ZXJHcm9iKHBhcmNobWVudCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IHVuaXQoMSwibnBjIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gdW5pdCgxLCJucGMiKSksIAogICAgICAgICAgICAgICAgICAgIC1JbmYsIEluZiwgLUluZiwgSW5mKSArCiAgZ2VvbV9lZGdlX2xpbmsoKSArCiAgZ2VvbV9ub2RlX3BvaW50KCkgKwogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkgKwogIGdndGl0bGUoIkhhbWlsdG9uOiBTa2lwIEJpZ3JhbXMiKQpgYGAKClRoaXMgaXMgZXhlYWN0bHkgdGhlIGtpbmQgb2YgZ3JhcGggSSBuZWVkIHRvIGJlIGFibGUgdG8gcHJvZHVjZSBmb3IgbXkgdGhlc2lzLiBUaGlzIGZ1biBleGFtcGxlIHdhcyBhIGdvb2Qgd2F5IHRvIHByYWN0aWNlIGN1dHRpbmcgdGhlIGV4dHJhIG9mZiBvZiB0aGUgZ3JhcGgsIGluIHByZXBhcmF0aW9uIGZvciB0aGUgZ3JhcGgga2VybmVsIG1ldGhvZHMuIFRoZSBuZXh0IHN0ZXAgd291bGQgYmUgdG8gbWFrZSB0aGVzZSBzdHlsZSBncmFwaHMgZm9yIE1hZGlzb24gYW5kIEpheS4gQWx0ZXJuYXRpdmVseSwgdGhleSBjb3VsZCBiZSBtYWRlIGZvciBlYWNoIGVzc2F5LiBUaGVuIGdyYXBoIGtlcm5lbHMgd2lsbCBiZSBhcHBsaWVkIGFuZCBhIG1lYXN1cmUgb2Ygc2ltaWxhcml0eSBiZXR3ZWVuIHRoZSBncmFwaHMgd2lsbCBiZSBwcm9kdWNlZC4KCiMgQ29uY2x1c2lvbnMKClVzaW5nIHRleHQgYW5hbHlzaXMsIHRoZSBGZWRlcmFsaXN0IHBhcGVycyBjYW4gYmUgYSBsb3Qgb2YgZnVuIHRvIHdvcmsgb24uIFRoZXJlIGFyZSBhIGxvdCBvZiBmdW4gdGFza3MgaGVyZTogc2VwZXJhdGUgdGV4dCBieSBhdXRob3IsIHNlcGVyYXRlIHRleHQgYnkgZXNzYXksIHdobyB3cm90ZSBfTm9uLVN0b3BfLCBhbmQgd2hvIGdvdCBzaWNrIGFmdGVyIHdyaXRpbmcgNT8gSW4gdGhpcyBwcm9qZWN0IEkgc3BlY2lmaWNhbGx5IHdhbnRlZCB0byBwcmFjdGljZSBzb21lIGB7Z2dwbG90Mn1gIHNraWxscy4gQW1vbmcgdGhvc2Ugc2tpbGxzIHdlcmU6IGB7Z2dhbm5vdGF0ZX1gLCBiYWNrZ3JvdW5kIGltYWdlcywgYW5kIHRoZW1lIGVsZW1lbnRzLiBBZGRpdGlvbmFsbHksIEkgd2FudGVkIHRvIGRvIHNvbWUgdGV4dCBhbmFseXNpcyB0byBwcmFjdGljZSBhbmQgbGVhcm4gaG93IHRvIHByZXBhcmUgbXkgZ3JhcGhzIGZvciB0aGUgYW5hbHlzaXMgSSB3YW50IHRvIGNvbXBsZXRlIGZvciBtZSB0aGVzaXMgd29yay4gCg==